package com.ontheroad.mysql.circle.service;

import cn.modoumama.page.PageObject;
import cn.modoumama.service.base.impl.BaseServiceImpl;
import com.google.common.collect.Maps;
import com.ontheroad.api.request.CircleRequest;
import com.ontheroad.api.request.Request;
import com.ontheroad.api.response.CircleResponse;
import com.ontheroad.api.response.Response;
import com.ontheroad.api.response.UserResponse;
import com.ontheroad.circle.model.CircleModel;
import com.ontheroad.circle.model.CircleTopicModel;
import com.ontheroad.circle.model.CommentModel;
import com.ontheroad.circle.service.CircleService;
import com.ontheroad.core.util.DateUtils;
import com.ontheroad.core.util.SpringUtils;
import com.ontheroad.leanCloud.event.PushToUserEvent;
import com.ontheroad.leanCloud.model.PushType;
import com.ontheroad.like.model.CircleLikeModel;
import com.ontheroad.mysql.circle.mapper.CircleMapper;
import com.ontheroad.mysql.circle.mapper.CircleTopicMapper;
import com.ontheroad.mysql.circle.mapper.CommentMapper;
import com.ontheroad.mysql.like.mapper.CircleLikeMapper;
import com.ontheroad.mysql.path.mapper.PathUserMapper;
import com.ontheroad.mysql.topic.mapper.TopicMapper;
import com.ontheroad.mysql.user.mapper.UserMapper;
import com.ontheroad.path.model.PathUserModel;
import com.ontheroad.path.service.PathService;
import com.ontheroad.user.model.UserModel;
import com.ontheroad.user.service.UserService;
import com.spatial4j.core.context.SpatialContext;
import com.spatial4j.core.distance.DistanceUtils;
import com.spatial4j.core.shape.Point;
import com.spatial4j.core.shape.Rectangle;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * Created by kedong on 2017/6/29 0029.
 */
@Service
@Transactional
public class CircleServiceImpl extends BaseServiceImpl<CircleModel, Integer> implements CircleService {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private CircleMapper mapper;

    @Autowired
    private CircleTopicMapper circleTopicMapper;

    @Autowired
    private TopicMapper topicMapper;

    @Autowired
    private CircleLikeMapper likeMapper;

    @Autowired
    private CommentMapper commentMapper;

    @Autowired
    private PathUserMapper pathMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private CircleLikeMapper circleLikeMapper;

    @Autowired
    private PathService pathService;

    @Autowired
    private UserService userService;

    @Autowired
    public void serMapper(CircleMapper mapper) {
        setGenericMapper(mapper);
    }


    /**
     * @param request
     * @return
     * @throws Exception
     */
    @Override
    public Response publish(CircleRequest request) throws Exception {
        CircleModel circleModel = new CircleModel();
        Integer userId = request.getUserId().intValue();
        circleModel.setUserid(userId);
        circleModel.setContent(request.getContent());
        circleModel.setImages(request.getImages());
        circleModel.setAddress(request.getAddress());
        circleModel.setLng(request.getLng());
        circleModel.setLat(request.getLat());
        circleModel.setCreateTime(new Date());
        circleModel.setPathid(request.getPathid());
        if (request.getCircleType() == 2 && request.getPathid() == null) {
            Response addPath = pathService.addPath(request);
            Integer pathId = (Integer) addPath.getResultMap().get("pathId");
            circleModel.setPathid(pathId);
        }
        UserModel user = userService.findById(userId);
        circleModel.setOfficial(user.getOfficial());
        mapper.insertModel(circleModel);

        /**
         * 参与话题
         */
        String topics = request.getTopics();
        if (StringUtils.isNotBlank(topics)) {
            List<Integer> topicIdList = new ArrayList<>();
            if (topics.contains(",")) {
                String[] topicIds = topics.split(",");
                for (String topicId : topicIds) {
                    topicIdList.add(Integer.parseInt(topicId));
                }
            } else {
                topicIdList.add(Integer.parseInt(topics));
            }

            for (Integer topicId : topicIdList) {
                CircleTopicModel circleTopicModel = new CircleTopicModel();
                circleTopicModel.setTopicId(topicId);
                circleTopicModel.setCircleId(circleModel.getId());
                circleTopicMapper.insertModel(circleTopicModel);
            }
            // 更新话题参与数
            topicMapper.updateAddParticipantsCountByIds(topicIdList);
        }

        Response response = Response.SUCCESS();
        response.addResultData("circleId", circleModel.getId());
        return response;
    }

    /**
     * 附近的动态列表 2017/6/29 0029
     * 区间查找的方式实现 5km范围内
     *
     * @param request
     * @return
     */
    @Override
    public Response getNearCircleList(CircleRequest request) throws Exception {
        double lng = Double.valueOf(request.getLng());
        double lat = Double.valueOf(request.getLat());
        int radius = request.getRadius();
        List<CircleModel> list = getListByRadius(request, radius);
        List<CircleResponse> circleResponses = getCircleList(list, request, true, request.getUserId().intValue());
        Response response = Response.SUCCESS();
        response.addResultData("list", circleResponses);
        return response;
    }

    @Override
    public Response getFriendCircleList(CircleRequest request) throws Exception {
        Integer userId = request.getUserId().intValue();
        List<Integer> friendIds = new ArrayList<>();
        friendIds.add(userId);
        friendIds.addAll(mapper.getFriendIds(userId));
        // 分页
        PageObject po = new PageObject();
        po.setCurrPage(request.getPageNum());
        po.setPageSize(request.getPageSize());
        RowBounds rowBounds = new RowBounds(po.getOffset(), po.getPageSize());
        List<CircleModel> list = mapper.getFriendCricleList(friendIds, rowBounds);
        List<CircleResponse> circleResponses = getCircleList(list, request, false, userId);
        Response response = Response.SUCCESS();
        response.addResultData("list", circleResponses);
        return response;
    }


    /**
     * 通过距离查找
     *
     * @param request
     * @param radius
     * @return
     */
    private List<CircleModel> getListByRadius(CircleRequest request, int radius) {
        double lng = Double.valueOf(request.getLng());
        double lat = Double.valueOf(request.getLat());
        SpatialContext geo = SpatialContext.GEO;
        Rectangle rectangle = geo.getDistCalc().calcBoxByDistFromPt(
                geo.makePoint(lng, lat), radius * DistanceUtils.KM_TO_DEG, geo, null);
        double lngMin = rectangle.getMinX();
        double lngMax = rectangle.getMaxX();
        double latMin = rectangle.getMinY();
        double latMax = rectangle.getMaxY();

        // 分页
        PageObject po = new PageObject();
        po.setCurrPage(request.getPageNum());
        po.setPageSize(request.getPageSize());
        RowBounds rowBounds = new RowBounds(po.getOffset(), po.getPageSize());
        List<CircleModel> list = mapper.findNearCicle(lngMin, lngMax, latMin, latMax, rowBounds);
        return list;
    }

    @Override
    public Response getUserCircleList(CircleRequest request) throws Exception {
        Integer targetId = request.getTargetId();
        Integer userId = request.getUserId().intValue();
        // 分页
        PageObject po = new PageObject();
        po.setCurrPage(request.getPageNum());
        po.setPageSize(request.getPageSize());
        RowBounds rowBounds = new RowBounds(po.getOffset(), po.getPageSize());
        List<CircleModel> list = mapper.getListByUserId(targetId, rowBounds);
        List<CircleResponse> circleResponses = getCircleList(list, request, false, userId);
        Response response = Response.SUCCESS();
        response.addResultData("list", circleResponses);
        return response;
    }

    /**
     * 封装动态列表
     *
     * @param list
     * @param isDistance 是否计算距离
     * @param request
     * @return
     */
    @Override
    public List<CircleResponse> getCircleList(List<CircleModel> list, CircleRequest request, boolean isDistance, Integer userId) {
        List<CircleResponse> circleResponses = new ArrayList<>();
        if (list.size() > 0) {
            SpatialContext geo = null;
            Point point1 = null;
            if (isDistance) {
                geo = SpatialContext.GEO;
                point1 = geo.makePoint(Double.valueOf(request.getLng()), Double.valueOf(request.getLat()));
            }
            Map<String, Object> querymap = new HashMap<>();
            UserModel user;
            for (CircleModel model : list) {
                CircleResponse response = new CircleResponse();
                response.setId(model.getId());
                response.setUserId(model.getUserid());
                user = model.getUser();
                if (user != null) {
                    response.setNick(user.getNick());
                    response.setPic(user.getPic());
                } else {
                    response.setOfficial(false);
                }
                response.setOfficial(model.getOfficial());
                response.setAddress(model.getAddress());
                response.setContent(model.getContent());
                response.setImages(model.getImages());
                response.setCreateTime(model.getCreateTime());
                response.setCommentCount(model.getCommentCount());
                response.setLikeCount(model.getLikeCount());
                if (userId != null) {
                    // 查询是否点赞
                    querymap.put("userId", userId);
                    querymap.put("circleId", model.getId());
                    List<CircleLikeModel> circleLikeModels = circleLikeMapper.findModelsByCondition(querymap);
                    response.setLike(circleLikeModels.size() > 0);
                }
                PathUserModel path = model.getPath();
                if (path != null) {
                    response.setKilometre(path.getKilometre());
                    response.setPathIconUrl(path.getPathIconUrl());
                    response.setTime(path.getTime());
                    response.setPathid(path.getId().intValue());
                    response.setPathName(path.getName());
                    response.setType(path.getType());
                }
                // 计算距离
                if (isDistance && StringUtils.isNotBlank(model.getLng()) && StringUtils.isNotBlank(model.getLat())) {
                    Point point2 = geo.makePoint(Double.valueOf(model.getLng()), Double.valueOf(model.getLat()));
                    double distance = geo.calcDistance(point1, point2);
                    BigDecimal b = new BigDecimal(distance);
                    double f1 = b.setScale(5, BigDecimal.ROUND_HALF_UP).doubleValue();
                    response.setDistance(f1);
                }
                circleResponses.add(response);
            }
            // 按照距离从近到远排序
            if (isDistance) {
                Collections.sort(circleResponses, new Comparator<CircleResponse>() {
                    @Override
                    public int compare(CircleResponse o1, CircleResponse o2) {
                        return o1.getDistance().compareTo(o2.getDistance());
                    }
                });
            }
        }
        return circleResponses;
    }

    @Override
    public Response getIndex(CircleRequest request) throws Exception {
        Integer userId = request.getUserId().intValue();
        // 查出好友列表
        // 分页
        PageObject po = new PageObject();
        po.setCurrPage(request.getPageNum());
        po.setPageSize(request.getPageSize());
        RowBounds rowBounds = new RowBounds(po.getOffset(), po.getPageSize());
        List<CircleModel> list = mapper.getIndexListByUserId(userId, rowBounds);
        Response response = Response.SUCCESS();
        response.addResultData("list", list);
        return response;
    }

    @Override
    public Response getCircleDetail(CircleRequest request) throws Exception {
        Integer circleId = request.getCircleId();
        CircleModel circleModel = mapper.getObjectById(circleId);
        if (circleModel == null) {
            return Response.FAILED("该动态已被删除。");
        }
        Integer pathId = circleModel.getPathid();
        if (pathId != null) {
            PathUserModel path = pathMapper.getObjectById(pathId.longValue());
            circleModel.setPath(path);
        }
        // 是否为官方动态
        UserModel user = circleModel.getUser();
        UserModel circleUser = new UserModel();
        circleUser.setId(user.getId());
        circleUser.setNick(user.getNick());
        circleUser.setPic(user.getPic());
        circleModel.setUser(circleUser);
        // 获取四条顶级评论
        request.setPageSize(4);
        // 查询评论列表
        List<CommentModel> commentList = commentList(request);
        // 获取7个点赞的用户
        List<UserResponse> likeList = likeList(circleId, request);
        request.setPageSize(7);
        Response response = Response.SUCCESS();
        response.addResultData("circle", circleModel);
        response.addResultData("commentList", commentList);
        response.addResultData("likeList", likeList);
        return response;
    }

    @Override
    public Response like(CircleRequest request) throws Exception {

        Integer userId = request.getUserId().intValue();

        CircleLikeModel likeModel = new CircleLikeModel();
        Integer circleId = request.getCircleId();
        likeModel.setCircleId(circleId);
        likeModel.setUserId(request.getUserId().intValue());
        List<CircleLikeModel> list = likeMapper.getListByModel(likeModel);
        if (list.size() == 0) {
            likeMapper.insertModel(likeModel);


            CircleModel circleModel = findById(circleId);
            if (circleModel != null) {
                Map<String, Object> data = new HashMap<>();
                /**
                 * 点赞人
                 */
                UserModel user = userMapper.getObjectById(userId);
                // 用户头像
                data.put("userIcon", user.getPic());
                // 用户昵称
                data.put("userName", user.getNick());
                String images = circleModel.getImages();
                String img = "";
                if (StringUtils.isNotBlank(images)) {
                    if (images.contains(",")) {
                        img = images.split(",")[0];
                    } else {
                        img = images;
                    }
                }
                //图片
                data.put("img", img);
                //时间
                data.put("time", DateUtils.dateToTimestamp(null));
                //1、动态，2、约伴
                data.put("type", 1);
                data.put("id", circleId);
                //通知类型
                data.put("action", PushType.LIKE.getValue());

                /**
                 * 推送给动态主人
                 */
                SpringUtils.publishEvent(new PushToUserEvent("点赞动态推送...", circleModel.getUserid(), data));
            }
        } else {
            Response.FAILED("已经点过赞了");
        }
        return Response.SUCCESS();
    }

    @Override
    public Response unLike(CircleRequest request) throws Exception {
        likeMapper.deleteByUserIdAndCircleId(request.getUserId().intValue(), request.getCircleId());
        return Response.SUCCESS();
    }

    /**
     * 评论
     *
     * @param request
     * @return
     */
    @Override
    public Response comment(CircleRequest request) throws Exception {
        String content = request.getContent();
        Integer circleId = request.getCircleId();
        Integer userId = request.getUserId().intValue();

        Date now = new Date();

        CommentModel commentModel = new CommentModel();
        commentModel.setCreateTime(now);
        commentModel.setUserid(request.getUserId().intValue());
        commentModel.setContent(content);
        commentModel.setCircleid(circleId);
        commentModel.setReplyedid(request.getReplyedId());
        commentMapper.insertModel(commentModel);
        Response response = Response.SUCCESS();
        response.addResultData("commentId", commentModel.getId());


        CircleModel circleModel = findById(circleId);
        if (circleModel != null) {
            Map<String, Object> data = new HashMap<>();
            UserModel user = userMapper.getObjectById(userId);
            // 用户头像
            data.put("userIcon", user.getPic());
            // 用户昵称
            data.put("userName", user.getNick());

            String images = circleModel.getImages();
            String img = "";
            if (StringUtils.isNotBlank(images)) {
                if (images.contains(",")) {
                    img = images.split(",")[0];
                } else {
                    img = images;
                }
            }
            //图片
            data.put("img", img);
            //时间
            data.put("time", DateUtils.dateToTimestamp(now));
            //内容
            data.put("content", content);
            //1、动态，2、约伴
            data.put("type", 1);
            data.put("id", circleId);
            //通知类型
            data.put("action", PushType.COMMENT.getValue());

            // 评论动态推送
            SpringUtils.publishEvent(new PushToUserEvent("评论动态推送...", circleModel.getUserid(), data));
        }

        return response;
    }

    @Override
    public Response getCommentList(CircleRequest request) throws Exception {
        List<CommentModel> commentList = commentList(request);
        Response response = Response.SUCCESS();
        response.addResultData("commentList", commentList);
        return response;
    }

    private List<CommentModel> commentList(CircleRequest request) {
        Integer circleId = request.getCircleId();
        // 分页
        PageObject po = new PageObject();
        po.setCurrPage(request.getPageNum());
        po.setPageSize(request.getPageSize());
        RowBounds rowBounds = new RowBounds(po.getOffset(), po.getPageSize());
        po.addCondition("circleid", circleId);
        po.addCondition("noParentid", true);
        // 查询评论列表
        List<CommentModel> commentList = commentMapper.findModelsByCondition(po.getCondition(), rowBounds);
        return commentList;
    }


    @Override
    public Response likeList(CircleRequest request) throws Exception {
        Integer circleId = request.getCircleId();
        List<UserResponse> list = likeList(circleId, request);
        Response response = Response.SUCCESS();
        response.addResultData("likeList", list);
        return response;
    }

    @Override
    public Response careChosenList(Request request) throws Exception {
        Response response = new Response();
        // 分页
        PageObject po = new PageObject();
        po.setCurrPage(request.getPageNum());
        po.setPageSize(request.getPageSize());
        po.addCondition("careChosen", true);
        List<CircleModel> list = findModelsByCondition(po);
        response.addResultData("list", list);
        return response;
    }

    @Override
    public Response delete(CircleRequest request) throws Exception {
        Integer circleId = request.getCircleId();
        mapper.deleteById(circleId);
        /**
         * 更新话题参与人数
         */
        Map<String, Object> map = Maps.newHashMap();
        map.put("circleId", circleId);
        List<CircleTopicModel> list = circleTopicMapper.findModelsByCondition(map);
        if (list != null && list.size() > 0) {
            List<Integer> topicIds = new ArrayList<>();
            for (CircleTopicModel circleTopicModel : list) {
                topicIds.add(circleTopicModel.getTopicId());
            }
            topicMapper.updateParticipantsCountByIds(topicIds);
        }
        // 删除关系
        circleTopicMapper.deleteByCircleId(circleId);

        return new Response();
    }

    @Override
    public void updateCareChooseByIds(Integer circleId, Boolean careChose) {
        mapper.updateCareChooseByIds(circleId, careChose);
    }

    /**
     * 查询点赞列表
     *
     * @param circleId
     * @param request
     * @return
     */
    private List<UserResponse> likeList(Integer circleId, CircleRequest request) {
        // 分页
        PageObject po = new PageObject();
        po.setCurrPage(request.getPageNum());
        po.setPageSize(request.getPageSize());
        RowBounds rowBounds = new RowBounds(po.getOffset(), po.getPageSize());
        // 查询点赞的用户列表
        List<UserModel> list = userMapper.getLikeListByCircleId(circleId, rowBounds);
        List<UserResponse> users = new ArrayList<>();
        for (UserModel userModel : list) {
            UserResponse user = new UserResponse();
            user.setUserId(userModel.getId());
            user.setNick(userModel.getNick());
            user.setPic(userModel.getPic());
            users.add(user);
        }
        return users;
    }

}